fetcher: Rework API to use strings for tls keys/db
authorColin Walters <walters@verbum.org>
Mon, 9 Jan 2017 15:02:19 +0000 (10:02 -0500)
committerAtomic Bot <atomic-devel@projectatomic.io>
Thu, 19 Jan 2017 10:47:15 +0000 (10:47 +0000)
This is prep for the libcurl porting. `GTlsCertificate/GTlsDatabase` are
abstract classes implemented in glib-networking for gnutls. curl's APIs take
file paths as strings, so it's easier to work on both if we move the GLib TLS
bits into the libsoup code.

Closes: #651
Approved by: giuseppe

src/libostree/ostree-fetcher.c
src/libostree/ostree-fetcher.h
src/libostree/ostree-repo-pull.c
src/libostree/ostree-tls-cert-interaction.c
src/libostree/ostree-tls-cert-interaction.h

index cee33186cbe8a6eb30e8ad0c48faf38fa2157fa6..a178abfe756c283556c9323ff8cc0690384810d5 100644 (file)
@@ -52,6 +52,7 @@ typedef struct {
   SoupSession *session;  /* not referenced */
   GMainContext *main_context;
   volatile gint running;
+  GError *initialization_error; /* Any failure to load the db */
 
   int tmpdir_dfd;
   char *tmpdir_name;
@@ -357,12 +358,14 @@ static void
 session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure,
                                        gpointer data)
 {
-  GTlsCertificate *cert = data;
+  const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */
+  const char *cert_path = cert_and_key_path;
+  const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1;
   glnx_unref_object OstreeTlsCertInteraction *interaction = NULL;
 
   /* The GTlsInteraction instance must be created in the
    * session thread so it uses the correct GMainContext. */
-  interaction = _ostree_tls_cert_interaction_new (cert);
+  interaction = _ostree_tls_cert_interaction_new (cert_path, key_path);
 
   g_object_set (thread_closure->session,
                 SOUP_SESSION_TLS_INTERACTION,
@@ -374,13 +377,19 @@ static void
 session_thread_set_tls_database_cb (ThreadClosure *thread_closure,
                                     gpointer data)
 {
-  GTlsDatabase *database = data;
+  const char *db_path = data;
 
-  if (database != NULL)
+  if (db_path != NULL)
     {
-      g_object_set (thread_closure->session,
-                    SOUP_SESSION_TLS_DATABASE,
-                    database, NULL);
+      glnx_unref_object GTlsDatabase *tlsdb = NULL;
+
+      g_clear_error (&thread_closure->initialization_error);
+      tlsdb = g_tls_file_database_new (db_path, &thread_closure->initialization_error);
+
+      if (tlsdb)
+        g_object_set (thread_closure->session,
+                      SOUP_SESSION_TLS_DATABASE,
+                      tlsdb, NULL);
     }
   else
     {
@@ -452,6 +461,13 @@ session_thread_request_uri (ThreadClosure *thread_closure,
   pending = g_task_get_task_data (task);
   cancellable = g_task_get_cancellable (task);
 
+  /* If we caught an error in init, re-throw it for every request */
+  if (thread_closure->initialization_error)
+    {
+      g_task_return_error (task, g_error_copy (thread_closure->initialization_error));
+      return;
+    }
+
   create_pending_soup_request (pending, &local_error);
   if (local_error != NULL)
     {
@@ -797,16 +813,24 @@ _ostree_fetcher_set_cookie_jar (OstreeFetcher *self,
 
 void
 _ostree_fetcher_set_client_cert (OstreeFetcher   *self,
-                                 GTlsCertificate *cert)
+                                 const char      *cert_path,
+                                 const char      *key_path)
 {
+  g_autoptr(GString) buf = NULL;
   g_return_if_fail (OSTREE_IS_FETCHER (self));
-  g_return_if_fail (G_IS_TLS_CERTIFICATE (cert));
+
+  if (cert_path)
+    {
+      buf = g_string_new (cert_path);
+      g_string_append_c (buf, '\0');
+      g_string_append (buf, key_path);
+    }
 
 #ifdef HAVE_LIBSOUP_CLIENT_CERTS
   session_thread_idle_add (self->thread_closure,
                            session_thread_set_tls_interaction_cb,
-                           g_object_ref (cert),
-                           (GDestroyNotify) g_object_unref);
+                           g_string_free (g_steal_pointer (&buf), FALSE),
+                           (GDestroyNotify) g_free);
 #else
   g_warning ("This version of OSTree is compiled without client side certificate support");
 #endif
@@ -814,24 +838,14 @@ _ostree_fetcher_set_client_cert (OstreeFetcher   *self,
 
 void
 _ostree_fetcher_set_tls_database (OstreeFetcher *self,
-                                  GTlsDatabase  *db)
+                                  const char    *tlsdb_path)
 {
   g_return_if_fail (OSTREE_IS_FETCHER (self));
-  g_return_if_fail (db == NULL || G_IS_TLS_DATABASE (db));
 
-  if (db != NULL)
-    {
-      session_thread_idle_add (self->thread_closure,
-                               session_thread_set_tls_database_cb,
-                               g_object_ref (db),
-                               (GDestroyNotify) g_object_unref);
-    }
-  else
-    {
-      session_thread_idle_add (self->thread_closure,
-                               session_thread_set_tls_database_cb,
-                               NULL, (GDestroyNotify) NULL);
-    }
+  session_thread_idle_add (self->thread_closure,
+                           session_thread_set_tls_database_cb,
+                           g_strdup (tlsdb_path),
+                           (GDestroyNotify) g_free);
 }
 
 void
index a57907e429fffa67436efafb8fbf7ee00adb3ed5..f19eb73b0dc100b4a98cc536014f8e33fbe445c1 100644 (file)
@@ -93,10 +93,11 @@ void _ostree_fetcher_set_proxy (OstreeFetcher *fetcher,
                                 const char    *proxy);
 
 void _ostree_fetcher_set_client_cert (OstreeFetcher *fetcher,
-                                     GTlsCertificate *cert);
+                                      const char     *cert_path,
+                                      const char     *key_path);
 
 void _ostree_fetcher_set_tls_database (OstreeFetcher *self,
-                                       GTlsDatabase *db);
+                                       const char    *tlsdb_path);
 
 void _ostree_fetcher_set_extra_headers (OstreeFetcher *self,
                                         GVariant      *extra_headers);
index 3dabb346333b446ceeb306f05be2740751ef573c..45995a30d03082d9d332ecfa08f4b5755413913d 100644 (file)
@@ -1951,17 +1951,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo  *self,
       }
     else if (tls_client_cert_path != NULL)
       {
-        g_autoptr(GTlsCertificate) client_cert = NULL;
-
-        g_assert (tls_client_key_path != NULL);
-
-        client_cert = g_tls_certificate_new_from_files (tls_client_cert_path,
-                                                        tls_client_key_path,
-                                                        error);
-        if (client_cert == NULL)
-          goto out;
-
-        _ostree_fetcher_set_client_cert (fetcher, client_cert);
+        _ostree_fetcher_set_client_cert (fetcher, tls_client_cert_path, tls_client_key_path);
       }
   }
 
@@ -1975,13 +1965,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo  *self,
 
     if (tls_ca_path != NULL)
       {
-        g_autoptr(GTlsDatabase) db = NULL;
-
-        db = g_tls_file_database_new (tls_ca_path, error);
-        if (db == NULL)
-          goto out;
-
-        _ostree_fetcher_set_tls_database (fetcher, db);
+        _ostree_fetcher_set_tls_database (fetcher, tls_ca_path);
       }
   }
 
index 846d5725fc3790b503485c9f0e78ec98f9349edf..7e60f9de4de09e224f604fe5feb6e98f5560538e 100644 (file)
@@ -24,6 +24,8 @@ struct _OstreeTlsCertInteraction
 {
   GTlsInteraction parent_instance;
 
+  char *cert_path;
+  char *key_path;
   GTlsCertificate *cert;
 };
 
@@ -44,6 +46,14 @@ request_certificate (GTlsInteraction              *interaction,
                      GError                      **error)
 {
   OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction*)interaction;
+
+  if (!self->cert)
+    {
+      self->cert = g_tls_certificate_new_from_files (self->cert_path, self->key_path, error);
+      if (!self->cert)
+        return G_TLS_INTERACTION_FAILED;
+    }
+
   g_tls_connection_set_certificate (connection, self->cert);
   return G_TLS_INTERACTION_HANDLED;
 }
@@ -61,9 +71,11 @@ _ostree_tls_cert_interaction_class_init (OstreeTlsCertInteractionClass *klass)
 }
 
 OstreeTlsCertInteraction *
-_ostree_tls_cert_interaction_new (GTlsCertificate *cert)
+_ostree_tls_cert_interaction_new (const char *cert_path,
+                                  const char *key_path)
 {
   OstreeTlsCertInteraction *self = g_object_new (OSTREE_TYPE_TLS_CERT_INTERACTION, NULL);
-  self->cert = g_object_ref (cert);
+  self->cert_path = g_strdup (cert_path);
+  self->key_path = g_strdup (key_path);
   return self;
 }
index c81097c5e395ed3472a3a3ceddb364e95e58a3b5..ae4532f7ba3f9b1986cb148435edc2cfd63284ee 100644 (file)
@@ -34,6 +34,7 @@ typedef struct _OstreeTlsCertInteractionClass   OstreeTlsCertInteractionClass;
 
 GType                       _ostree_tls_cert_interaction_get_type    (void) G_GNUC_CONST;
 
-OstreeTlsCertInteraction *  _ostree_tls_cert_interaction_new         (GTlsCertificate *cert);
+OstreeTlsCertInteraction *  _ostree_tls_cert_interaction_new         (const char *cert_path,
+                                                                      const char *key_path);
 
 G_END_DECLS